import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import cn.abcsys.devops.core.Deployer;
import cn.abcsys.devops.core.deployer.Scheduler;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ContainerPort;
import io.fabric8.kubernetes.api.model.LocalObjectReference;
import io.fabric8.kubernetes.api.model.NFSVolumeSource;
import io.fabric8.kubernetes.api.model.ReplicationController;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServicePort;
import io.fabric8.kubernetes.api.model.Volume;
import io.fabric8.kubernetes.api.model.VolumeMount;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;

public class Main implements Deployer {

	public String getUUID() {
		// TODO Auto-generated method stub
		return null;
	}

	public Object create(String runtimeUUID, String instanceName, String imageName, String imageVersion, String cpuSet, int memSize,
			String network, Map<String, String> envs, Map<String, String> volumes, Properties props) throws Exception {
		KubernetesClient client = createK8sClient(runtimeUUID);
		
		
		List<ContainerPort> ports = new ArrayList<ContainerPort>();
		ContainerPort port = new ContainerPort();
		
		List<Container> containers = new ArrayList<Container>();
		Container container = new Container();
		container.setName(instanceName);
		container.setImage(imageName + ":" +imageVersion);
		container.setPorts(ports);
		
		List<VolumeMount> volumeMounts = new ArrayList<VolumeMount>();
		VolumeMount volume = new VolumeMount();
		volume.setName(instanceName);
		volume.setMountPath("/home");
		volumeMounts.add(volume);
	
		container.setVolumeMounts(volumeMounts);
		
		containers.add(container);
		
		String value = props.getProperty("namespace");
		String namespace = (value == null) ? "default" : value;
		
		Map<String, String> selector = new HashMap<String, String>();
		selector.put("name", instanceName);
		
		Map<String, String> labels = new HashMap<String, String>();
		labels.put("name", instanceName);
		
		List<LocalObjectReference> imagePullSecrets = new ArrayList<LocalObjectReference>();
		LocalObjectReference lof = new LocalObjectReference();
		lof.setName(props.getProperty("secret"));
		imagePullSecrets.add(lof);
		
		List<Volume> vols = new ArrayList<Volume>();
		Volume vol = new Volume();
		NFSVolumeSource nfs = new NFSVolumeSource();
		nfs.setServer("kube-master");
		nfs.setPath("/opt/NfsFileSystem");
		vol.setNfs(nfs);
		vol.setName(instanceName);
		vols.add(vol);
		
		ReplicationController controller = client.replicationControllers()
										.createNew()
										.withApiVersion("v1")
										.withKind("ReplicationController")
										.withNewMetadata()
										.withName(instanceName)
										.withNamespace(namespace)
										.endMetadata()
										.withNewSpec()
										.withReplicas(1)
										.withSelector(selector)
										.withNewTemplate()
										.withNewMetadata()
										.withName(instanceName)
										.withNamespace(namespace)
										.withLabels(labels)
										.endMetadata()
										.withNewSpec()
										.withContainers(containers)
										.withImagePullSecrets(imagePullSecrets)
										.withVolumes(vols)
										.endSpec()
										.endTemplate()
										.endSpec()
										.done();
		return controller;
	}

	private KubernetesClient createK8sClient(String url) {
		Config config = new ConfigBuilder().withMasterUrl(url).build();
		KubernetesClient client = new DefaultKubernetesClient(config);
		return client;
	}

	
	public Object start(String runtimeUUID, String instanceName, Properties props) throws Exception {
		KubernetesClient client = createK8sClient(runtimeUUID);
		
		String value = props.getProperty("namespace");
		String namespace = (value == null) ? "default" : value;
		
		List<ServicePort> ports = new ArrayList<ServicePort>();
		ServicePort sp = new ServicePort();
		sp.setPort(8080);
		ports.add(sp);
//		sp.setTargetPort(targetPort);
		
		Map<String, String> selector = new HashMap<String, String>();
		selector.put("name", instanceName);
		
		Service service = client.services().createNew()
											.withApiVersion("v1")
											.withKind("Service")
											.withNewMetadata()
											.withName(instanceName)
											.withNamespace(namespace)
											.endMetadata()
											.withNewSpec()
											.withType("NodePort")
											.withPorts(ports)
											.withSelector(selector)
											.endSpec()
											.done();
		return service;
	}

	public Object migrate(String runtimeUUID, String instanceUUID, String targetHost) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public Object stop(String runtimeUUID, String instanceUUID) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public Object delete(String runtimeUUID, String instanceUUID) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public Scheduler getScheduler() {
		// TODO Auto-generated method stub
		return null;
	}

	public Object setScheduler(Scheduler scheduler) {
		// TODO Auto-generated method stub
		return null;
	}

    public static void main(String[] args) throws Exception {
    	Map<String, String> envs = new HashMap<String, String>();
    	envs.put("test", "test");
    	
    	Map<String, String> volumes = new HashMap<String, String>();
    	volumes.put("/home", "/opt/NfsFileSystem/home");
    	
    	Properties props = new Properties();
    	props.put("namespace", "default");
    	props.put("secret", "my-secret");
    	
    	Main main = new Main();
//    	ReplicationController rc = (ReplicationController) main.create("http://133.133.134.104:8080", "henry-tomcat",
//    			"registry.cn-hangzhou.aliyuncs.com/xuyuanjia/docker", "tomcat-centos", 
//    			"0-1", 1024, "bridge", 
//    			envs, volumes, props);
    	Service service = (Service) main.start("http://133.133.134.104:8080", "henry-tomcat", props);
    	System.out.println(service.getStatus());
	}
}
